package top.crossrun.webview.bridge.core.pls;

import android.content.Intent;
import android.text.TextUtils;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;

import top.crossrun.webview.bridge.core.utils.BridgeUtil;


/**
 *
 */
public abstract class WebViewBridgePluginManagerAdapter implements WebViewBridgePluginManager, WebViewActivityLife {
    private Map<String, WebViewBridgePlugin> plugins;
    private Map<String, Class<? extends WebViewBridgePlugin>> pluginLazy;
    private Map<String, WebViewActivityLife> activityLifeMap;
    private Map<String, Integer> requestCodes;
    private final int start = 10000;
    private int p = start;
    private BridgeJSEval jsEval;

    public WebViewBridgePluginManagerAdapter(BridgeJSEval jsEval) {
        plugins = new HashMap<>();
        pluginLazy = new HashMap<>();
        activityLifeMap = new HashMap<>();
        requestCodes = new HashMap<>();
        this.jsEval = jsEval;
    }

    @Override
    public WebViewBridgePlugin getBridgePlugin(String name) {
        WebViewBridgePlugin w = plugins.get(name);
        if (w == null) {
            Class<? extends WebViewBridgePlugin> clazz = pluginLazy.get(name);
            if (clazz != null) {
                try {
                    w = clazz.newInstance();
                    pluginRegister(w);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
        return w;
    }

    @Override
    public void pluginRegister(WebViewBridgePlugin webViewBridgePlugin) {
        if (TextUtils.isEmpty(webViewBridgePlugin.getPluginName())) {
            return;
        }
        if (webViewBridgePlugin.getBridgePluginManager() == null) {
            webViewBridgePlugin.setBridgePluginManager(this);
        }
        plugins.put(webViewBridgePlugin.getPluginName(), webViewBridgePlugin);
        if (BridgeUtil.isAssginFromActivityLife(webViewBridgePlugin.getClass())) {
            activityLifeMap.put(webViewBridgePlugin.getPluginName(), (WebViewActivityLife) webViewBridgePlugin);
        }
    }

    @Override
    public void pluginRegister(String name, Class<? extends WebViewBridgePlugin> s) {
        pluginLazy.put(name, s);
    }

    @Override
    public void pluginRegister(String handlerName, WebViewBridgeHandler handler, boolean needContext) {
        if (TextUtils.isEmpty(handlerName) || handler == null) {
            return;
        }
        pluginRegister(new DefaultWebViewPlugin(handlerName, handler, needContext));
    }

    private void releaseAllBridge() {
        Set<Map.Entry<String, WebViewBridgePlugin>> entries = plugins.entrySet();
        for (Map.Entry<String, WebViewBridgePlugin> entry : entries) {
            WebViewBridgePlugin iface = entry.getValue();
            if (iface != null) {
                iface.onDestroy();
            }
        }
        plugins.clear();
        pluginLazy.clear();
        activityLifeMap.clear();
        requestCodes.clear();
    }

    @Override
    public int getRequestCode(String pluginName, String methodName) {
        Integer code = requestCodes.get(pluginName + methodName);
        if (code == null) {
            p++;
            requestCodes.put(pluginName + methodName, p);
            return p;
        }
        return code;
    }

    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        Set<Map.Entry<String, WebViewActivityLife>> entries = activityLifeMap.entrySet();
        for (Map.Entry<String, WebViewActivityLife> entry : entries) {
            WebViewActivityLife iface = entry.getValue();
            if (iface != null) {
                iface.onActivityResult(requestCode, resultCode, data);
            }
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        Set<Map.Entry<String, WebViewActivityLife>> entries = activityLifeMap.entrySet();
        for (Map.Entry<String, WebViewActivityLife> entry : entries) {
            WebViewActivityLife iface = entry.getValue();
            if (iface != null) {
                iface.onRequestPermissionsResult(requestCode, permissions, grantResults);
            }
        }
    }

    @Override
    public void onResume() {
        Set<Map.Entry<String, WebViewActivityLife>> entries = activityLifeMap.entrySet();
        for (Map.Entry<String, WebViewActivityLife> entry : entries) {
            WebViewActivityLife iface = entry.getValue();
            if (iface != null) {
                iface.onResume();
            }
        }
    }

    @Override
    public void onPause() {
        Set<Map.Entry<String, WebViewActivityLife>> entries = activityLifeMap.entrySet();
        for (Map.Entry<String, WebViewActivityLife> entry : entries) {
            WebViewActivityLife iface = entry.getValue();
            if (iface != null) {
                iface.onPause();
            }
        }
    }

    @Override
    public void onStart() {
        Set<Map.Entry<String, WebViewActivityLife>> entries = activityLifeMap.entrySet();
        for (Map.Entry<String, WebViewActivityLife> entry : entries) {
            WebViewActivityLife iface = entry.getValue();
            if (iface != null) {
                iface.onStart();
            }
        }
    }

    @Override
    public void onStop() {
        Set<Map.Entry<String, WebViewActivityLife>> entries = activityLifeMap.entrySet();
        for (Map.Entry<String, WebViewActivityLife> entry : entries) {
            WebViewActivityLife iface = entry.getValue();
            if (iface != null) {
                iface.onStop();
            }
        }
    }

    @Override
    public BridgePluginMsg getBridgePluginMsg(BridgePluginMsg msg) {
        return null;
    }

    @Override
    public void loadUrl(String url) {
        jsEval.loadUrl(url);
    }

    @Override
    public BridgeJSEval getJSEval() {
        return jsEval;
    }

    @Override
    public String getBridgeJS() {
        return BJS.js;
    }

    @Override
    public void onDestroy() {
        jsEval.onDestory();
        releaseAllBridge();
    }
}
